home *** CD-ROM | disk | FTP | other *** search
-
- -- This file describes the new Spawn System (Matt Miner 3-27-06)
-
- ---------------------------------------------------------------------------
- -- SPAWNING LOCATION CODE
- -- These are default functions that can be used to specify
- -- where invaders spawn from. Feel free to add more. NOTE:
- -- The function must take no parameters and return a Vector3
- ---------------------------------------------------------------------------
-
- -- Randomly positioned in a circle around the tower
- function CircleAroundTower()
- local centerPos = Vector3( 256, 0, 256 );
-
- local tower = G.GetCogName("Tower")
- -- Check that the tower still exists, and get it's center:
- if( tower ~= nil and tower.IsValid() ) then
- centerPos = tower.GetPosition()
- end
-
- -- Get a value between 0 and 2*PI
- local randpos = math.random() * 2.0 * math.pi;
- return Vector3( centerPos.x + math.cos(randpos) * 128, centerPos.y, centerPos.z + math.sin(randpos) * 128 );
- end
-
- -- Randomly positioned in a circle around the tower
- function SmallCircleAroundTower()
- local centerPos = Vector3( 256, 0, 256 );
-
- local tower = G.GetCogName("Tower")
- -- Check that the tower still exists, and get it's center:
- if( tower ~= nil and tower.IsValid() ) then
- centerPos = tower.GetPosition()
- end
-
- -- Get a value between 0 and 2*PI
- local randpos = math.random() * 2.0 * math.pi;
- return Vector3( centerPos.x + math.cos(randpos) * 64, centerPos.y, centerPos.z + math.sin(randpos) * 64 );
- end
-
- -- Anywhere valid on the map --changed by STEFAN to stay closer to center (assuming 512 x 512 grid) NOTE: is only used when close to right side of map
- function RandomAnywhere()
- local centerPos = Vector3( 256, 0, 256 );
-
- local tower = G.GetCogName("Tower")
- -- Check that the tower still exists, and get it's center:
- if( tower ~= nil and tower.IsValid() ) then
- centerPos = tower.GetPosition()
- end
-
- return centerPos + Vector3( math.random( 180 ) - 90, 0, math.random( 180 ) - 90 );
- end
-
- SpawnPoints = {}
-
- -- Uses "SpawnPoints" list of positions to use:
- function HardCodedSpawnPoints()
-
- local spawnPos = Vector3(0,0,0)
-
- if SpawnPoints ~= nil then
- -- Choose a random (valid) value
- local maxSpawnNum = SpawnPoints.NumPoints
- local curSpawnPoint = math.random( maxSpawnNum )
-
- -- If the random index did not exist, get the next valid one
- if ( SpawnPoints[ curSpawnPoint ] == nil ) then
- curSpawnPoint = next( SpawnPoints, curSpawnPoint )
-
- -- if the spawn point is still invalid (moved outside of list) get the first value:
- if( curSpawnPoint == nil ) then
- curSpawnPoint = next( SpawnPoints )
- end
-
- end
-
- if SpawnPoints[ curSpawnPoint ] ~= nil then
- spawnPos = SpawnPoints[ curSpawnPoint ]
- end
- end
-
- return spawnPos
-
- end
-
- ---------------------------------------------------------------------------
- -- SPAWN WAVE STRUCTURE
- -- This is the definition for the spawn wave structure used
- -- by the spawn system. The structure contains stats, spawning
- -- probabilities, and Several Spawning functions.
- ---------------------------------------------------------------------------
-
- -- Manually updates the probability totals
- function InitUpdateTotalProbabilty( self )
-
- self.ProbTotal = 0;
- for invadername,prob in pairs( self.Prob ) do
- self.ProbTotal = self.ProbTotal + prob;
- end
- end
-
- -- Increments time, and checks if a spawn should be done now:
- function InitShouldSpawn( self )
-
- -- Update the time
- self.SpawnTime = self.SpawnTime + self.SpawnSpeed * GameTimeDiff
-
- if( self.TotalSpawn ~= nil ) then
- if( self.TotalSpawn <= 0 ) then
- return false;
- end
- end
-
- if( self.SpawnTime > self.NextGroupSize ) then
-
- -- Prevent overflow (Affected by choppy framerates)
- self.SpawnTime = self.NextGroupSize
-
- -- Check what the restriction on # of invaders is
- return ( self.MaxSpawn >= NumInvaders + self.NextGroupSize )
-
- end
-
- return false
- end
-
- randomOffsets = {}
- randomOffsets[1] = Vector3( 0, 0, 0 )
- randomOffsets[2] = Vector3( 3, 0.5, 0 )
- randomOffsets[3] = Vector3( 0, 0.25, 3 )
- randomOffsets[4] = Vector3( 3, 0, 3 )
- randomOffsets[5] = Vector3(-3, -0.5, 0 )
- randomOffsets[6] = Vector3( 0, 0,-3 )
- randomOffsets[7] = Vector3(-3, 0.25,-3 )
- randomOffsets[8] = Vector3(-6, -0.25, 6 )
- randomOffsets[9] = Vector3( 6, 0.5,-6 )
- randomOffsets[10] = Vector3( 6, 0, 6 )
-
- -- Knowing that a spawn is valid (May be called by level) spawn it
- function InitDoSpawn( self )
-
- local spawnPos = self.WhereToSpawn()
-
- self:UpdateTotalProbabilty( )
-
-
-
- for curInvNum = 1, self.NextGroupSize do
- -- Find What type to spawn
- local rand = math.random();
- rand = rand * self.ProbTotal;
-
- local total;
- total = 0.0;
- for invadername,prob in pairs( self.Prob ) do
- total = total + prob;
-
- -- Spawn it
- if( total > rand ) then
- local invader = G.Allocate( invadername );
-
- -- Apply a small random offset from the given position to lessen stacking with groups:
- offset = randomOffsets[curInvNum] -- Vector3(( math.random() - 0.5 )* 2.0, 0, ( math.random() - 0.5 )* 2.0 )
-
- invader.SetPosition( spawnPos + offset );
-
- -- Have the invader move away from the position:
- invader.SetVelocity( offset );
-
- invader.Init();
-
- self.SpawnTime = self.SpawnTime - 1;
-
- --
- if( self.TotalSpawn ~= nil ) then
- self.TotalSpawn = self.TotalSpawn - 1
- if( self.TotalSpawn == 0 and self.FinishCallback ~= nil ) then
- self.FinishCallback()
- end
- end
-
- break;
- end
- end
- end
-
- -- Update for the next spawn:
- if math.random() < self.GroupPercent then
- self.NextGroupSize = self.GroupSize
- if( self.TotalSpawn ~= nil and self.NextGroupSize > self.TotalSpawn ) then
- self.NextGroupSize = self.TotalSpawn;
- end
- else
- self.NextGroupSize = 1
- end
-
-
- end
-
- -- This creates the structure used for the spawning system.
- function createSpawnStruct( )
-
- local spawnStruct = {}
-
- -- SPAWN STATS --
- spawnStruct.SpawnSpeed = 0.0;
- spawnStruct.MaxSpawn = 0; -- Simultaneous
- spawnStruct.TotalSpawn = nil; -- Ever (nil if infinite)
- spawnStruct.GroupPercent = 0.0;
- spawnStruct.GroupSize = 1;
- spawnStruct.WhereToSpawn = RandomAnywhere
- spawnStruct.FinishCallback = nil -- Called when the wave finished spawning
-
- -- INVADER SPAWN PERCENTS: --
- spawnStruct.Prob = {};
- spawnStruct.Prob.Miner = 0.0;
- spawnStruct.Prob.Squad = 0.0;
- spawnStruct.Prob.Bomber = 0.0;
- spawnStruct.Prob.Kamikaze = 0.0;
- spawnStruct.Prob.Driller = 0.0;
- spawnStruct.Prob.Psychic = 0.0;
- spawnStruct.Prob.Ninja = 0.0;
- spawnStruct.Prob.Spiker = 0.0;
- spawnStruct.Prob.Stacker = 0.0;
- spawnStruct.Prob.Basic = 0.0;
- spawnStruct.ProbTotal = 0.0; -- Total probabilty for all groups, updated manually.
-
- -- INTERNAL VARIABLES --
- spawnStruct.SpawnTime = 0.0; -- Timing variable used to determine if enough time has passed to spawn (>1.0)
- spawnStruct.NextGroupSize = 1;
-
- spawnStruct.UpdateTotalProbabilty = InitUpdateTotalProbabilty
- spawnStruct.ShouldSpawn = InitShouldSpawn;
- spawnStruct.DoSpawn = InitDoSpawn;
-
- return spawnStruct;
- end
-
- ------------------- EXAMPLE WAVES ---------------------
- DefaultWaveStruct = createSpawnStruct()
-
- ------------------- EXAMPLE WAVES ---------------------
- BasicWave = createSpawnStruct()
-
- BasicWave.Prob.Basic = 1.0;
-
- BasicWave.SpawnSpeed = 0.5;
- BasicWave.MaxSpawn = 25;
- BasicWave.GroupPercent = 0.1;
- BasicWave.GroupSize = 3;
- BasicWave.WhereToSpawn = CircleAroundTower
-
- ------------------- EXAMPLE WAVES ---------------------
- ExposiveWave = createSpawnStruct()
-
- ExposiveWave.Prob.Kamikaze = 0.5;
- ExposiveWave.Prob.Bomber = 1.0;
-
- ExposiveWave.SpawnSpeed = 0.5;
- ExposiveWave.MaxSpawn = 25;
- ExposiveWave.GroupPercent = 0.1;
- ExposiveWave.GroupSize = 3;
- ExposiveWave.WhereToSpawn = CircleAroundTower
-
- ---------------------------------------------------------------------------
- -- SPAWNING CODE
- -- This is the code used to set up the spawning of invaders.
- -- To use: 1. Create a new spawn wave using the createSpawnStruct() function.
- -- 2. Call AddWave() and pass the new wave in, allong with an ID. (String or integer)
- -- 3. Call StopWave() and pass the ID of the wave to be stopped.
- ---------------------------------------------------------------------------
-
- SpawnWaves = {}
-
- -- Adds a new wave to the given ID
- function AddWave( waveID, waveStruct )
- waveStruct.SpawnTime = 0
-
- if( SpawnWaves[waveID] == nil ) then
- SpawnWaves[waveID] = waveStruct
- else
- -- The spawn wave already existed here.
- -- For now, this will override the existing wave.
- SpawnWaves[waveID] = waveStruct
- end
- end
-
- -- Stop the given wave number
- function StopWave( waveID )
- if( SpawnWaves[waveID] ~= nil ) then
- SpawnWaves[waveID] = nil
- end
- end
-
- -- End (erase) all waves
- function EndAllWaves()
- SpawnWaves = nil
- SpawnWaves = {}
- end
-
-
- -- Update all SpawnWaves
- function SpawnSystemUpdate()
-
- for waveID, waveStruct in pairs( SpawnWaves ) do
- if( waveStruct:ShouldSpawn( ) ) then
- waveStruct:DoSpawn( )
- end
- end
- end
-
- -- Gmain: Automatic Updated Function List
- GMain[ "SpawnSystemUpdate" ] = SpawnSystemUpdate;